package com.buba.aspect.controller;

import com.buba.aspect.pojo.Log;
import com.buba.aspect.service.LogService;
import com.buba.system.pojo.Employee;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.TestComponent;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日志管理切面类
 * 用于监控用户在项目中执行的所有动作
 */
@Aspect
@Component
@TestComponent
public class LogAspect {
    private LogService logService;

    /**
     * add
     */
    @Pointcut("execution(public* com.buba.*.controller.*.add*(..))")
    private void add(){}
    /**
     * add
     */
    @Pointcut("execution(public* com.buba.*.controller.*.del*(..))")
    private void del(){}
    /**
     * add
     */
    @Pointcut("execution(public* com.buba.*.controller.*.sel*(..))")
    private void sel(){}
    /**
     * add
     */
    @Pointcut("execution(public* com.buba.*.controller.*.upd*(..))")
    private void upd(){}

    @Pointcut("add()||sel()||upd()||del()")
    private void buba(){}
    //前置通知
    @Before(value="buba()")
    public void before(JoinPoint joinPoint) {
//        System.out.println("前置通知：获得目标类名："+joinPoint.getTarget().getClass().getName());
//        System.out.println("前置通知：获得目标方法签名："+joinPoint.getSignature());
//        System.out.println(employeeId);
        //查询类名
//        System.out.println("caaaa+"+joinPoint.getTarget().getClass().getSimpleName());
        //查询方法名字
//        System.out.println("bbbbbb+"+joinPoint.getSignature().getName());
        //实例化对象
        Log log = new Log();
        //获取session
        ServletRequestAttributes attr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
        HttpSession session=attr.getRequest().getSession(true);
        Employee employee = (Employee)session.getAttribute("employee");
        if(employee!=null){
          log.setLoginName(employee.getEmployeeId());
          //只设置方法名
          log.setAction(joinPoint.getSignature().getName());
          DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
          log.setTime(dateFormat.format(new Date()));
          // 执行添加日志方法
          logService.Tlog(log);
      }
    }
    //后置通知
    @AfterReturning(value = "execution(public * com.buba.*.service.*.*(..))&& args(employeeId)",returning = "res")
    public void afterReturning(JoinPoint joinPoint,Object res,String employeeId) {
////        获取传入目标方法的参数对象
//        System.out.println("-----" + Arrays.toString(joinPoint.getArgs()));
////            获取被代理的对象
//        System.out.println("-----1" + joinPoint.getTarget());
////        获取代理对象
//        System.out.println("-----2" + joinPoint.getThis());
//        Signature signature = joinPoint.getSignature();
//        String s = signature.toLongString();
//        System.out.println(s);
//        System.out.println("111111+"+employeeId);

    }

    //环绕通知:ProceedingJoinPoint中的proceed()的执行就是执行目标方法
    @Around("execution(public * com.buba.*.service.*.*(..))")
    public Object around(ProceedingJoinPoint pjp) {
        Object res=null;
        try {
//            System.out.println("环绕通知的前置增强");
            res = pjp.proceed();
//            System.out.println("环绕通知的后置增强");
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return res;
    }

    //异常通知：异常 通知可以包含一个Throwable类型的参数，其参数名e和配置中的throwing指定名相同，表示当前发生的异常对象
    @AfterThrowing(value = "execution(public * com.buba.*.service.*.*(..))",throwing = "e")
    public void afterThrowing(Throwable e) {
        System.out.println("异常通知，异常类型为："+e.getClass().getName());
    }

    @Autowired
    @Qualifier("logServiceImpl")
    public void setLogService(LogService logService) {
        this.logService = logService;
    }
}
